package org.diysearch.dao.impls;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.diysearch.dao.filters.LinkFilter;
import org.diysearch.dao.interfaces.LinkDao;
import org.diysearch.helpers.CommentHelper;
import org.diysearch.helpers.TagHelper;
import org.diysearch.interfaces.Constants;
import org.diysearch.models.Comment;
import org.diysearch.models.Link;
import org.diysearch.models.Tag;
import org.diysearch.tools.StringTools;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class LinkDaoImpl extends SqlMapClientDaoSupport implements LinkDao {
	private static final Log LOG = LogFactory.getLog(LinkDaoImpl.class);
	
	@Override
	public int delete(Link link) throws SQLException {
		// delete the comments
		int code = 0;
		try {
			int dc = CommentHelper.deleteComments(link.getId(), Constants.LINKS_OBJECT_ID);
			LOG.info("deleted " + dc + " comments for link: " + link.getId());
		} catch (Exception ex) {
			throw new SQLException ("could not delete comments for link: " + link.getId());
		}
		if (link.getOwner() > 0) {
			// delete links from an owner
			code += getSqlMapClientTemplate().delete("delete-link-by-owner",link);
		} else {
			// just delete a link
			code += getSqlMapClientTemplate().delete("delete-link",link);
		}
		return code; 
	}

	@Override
	public int delete(List<Link> links) throws SQLException {
		int del = 0;
		for (Link link : links) {
			try {
				int dc = CommentHelper.deleteComments(link.getId(), Constants.LINKS_OBJECT_ID);
			} catch (Exception ex) {
				LOG.warn("had a problem deleting comments for link: " + link.getId());
				LOG.warn(StringTools.getStackTrace(ex));
			}
			del += getSqlMapClientTemplate().delete("delete-link",link);
		}
		return del;
	}

	@Override
	public int move(LinkFilter filter) throws SQLException {
		return getSqlMapClientTemplate().update("move-from-category",filter);
	}

	@Override
	public List<Link> findByCategory(LinkFilter filter) throws SQLException {
		 List<Link> links = getSqlMapClientTemplate().queryForList("findByCategory",filter);
		 try {
			 links = seed(links);
		 } catch (Exception ex) {
			 throw new SQLException (StringTools.getStackTrace(ex));
		 }
		 
		 return links;
	}

	@Override
	public List<Link> findByFilter(LinkFilter filter) throws SQLException {
		List<Link> links = getSqlMapClientTemplate().queryForList("findByFilter",filter);
		try {
			links = seed(links);
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return links;
	}

	@Override
	public Link findById(int id, int status) throws SQLException {
		LinkFilter filter =  new LinkFilter();
		filter.setStatus(status);
		filter.setLid(id);
		Link link = (Link) getSqlMapClientTemplate().queryForObject("findById",filter);
		try {
			List<Tag> tags = getTags(link);
			List<Comment> comments = getComments(link);
			if (tags != null && tags.size() > 0) {
				link.setTags(tags);
			}
				
			if (comments != null && comments.size() > 0) {
					link.setComments(comments);
			}
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return link;
	}

	@Override
	public List<Link> findByOwner(LinkFilter filter) throws SQLException {
		List<Link> links = getSqlMapClientTemplate().queryForList("findByOwner",filter);
		try {
			links = seed(links);
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return links;
	}

	@Override
	public List<Link> findByStatus(int status) throws SQLException {
		LinkFilter filter = new LinkFilter();
		filter.setStatus(status);
		List<Link> links = getSqlMapClientTemplate().queryForList("findByStatus",filter);
		try {
			links = seed(links);
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return links;
	}

	@Override
	public List<Link> findByTag(LinkFilter filter) throws SQLException {
		List<Link> links = getSqlMapClientTemplate().queryForList("findByTag",filter);
		try {
			links = seed(links);
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return links;
	}
	
	@Override
	public List<Link> findByEditorPick(LinkFilter filter) throws SQLException {
		List<Link> links = getSqlMapClientTemplate().queryForList("findEditorLinks",filter);
		
		try {
			links = seed(links);
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return links;
	}

	@Override
	public List<Link> findByRating(LinkFilter filter) throws SQLException {
		List<Link> links = getSqlMapClientTemplate().queryForList("findLinksByRating",filter);
		try {
			links = seed(links);
		} catch (Exception ex) {
			throw new SQLException (StringTools.getStackTrace(ex));
		}
		return links;
	}

	@Override
	public int save(Link link) throws SQLException {
		int code= 0;
		if (link.getId() == 0) {
			return ((Link) getSqlMapClientTemplate().insert("insert-link",link)).getId();
		} else {
			code = getSqlMapClientTemplate().update("update-link",link);
		}
		return code;
	}

	@Override
	public int save(List<Link> links) throws SQLException {
		int code = 0;
		for (Link link : links) {
			code += save(link);
		}
		return code;
	}

	@Override
	public int incrementClickthru(Link link) throws SQLException {
		return getSqlMapClientTemplate().update("increment-clickthrus",link);
	}

	@Override
	public int incrementImpression(Link link) throws SQLException {
		return getSqlMapClientTemplate().update("increment-impressions",link);
	}

	@Override
	public int setAsActive(Link link) throws SQLException {
		return getSqlMapClientTemplate().update("set-active",link);
	}

	@Override
	public int setAsEditorPick(Link link) throws SQLException {
		return getSqlMapClientTemplate().update("set-editor-pick",link);
	}

	@Override
	public int deincrementRating(Link link) throws SQLException {
		return getSqlMapClientTemplate().update("deincrement-rating",link);
	}

	@Override
	public int incrementRating(Link link) throws SQLException {
		return getSqlMapClientTemplate().update("increment-rating",link);
	}
	
	private List<Tag> getTags (Link l) throws Exception {
		if (l == null) throw new Exception ("link was null!!!!!!");
		return TagHelper.getTags(l.getId(), Constants.LINKS_OBJECT_ID);
	}
	
	private List<Comment> getComments (Link link) throws Exception {
		return CommentHelper.getComments(link.getId(), Constants.LINKS_OBJECT_ID);
	}
	
	private List<Link> seed(List<Link> links) throws Exception {
		List<Link> l = new ArrayList<Link>();
		for (Link link : links) {
			List<Tag> tags = getTags(link);
			List<Comment> comments = getComments(link);
			if (tags != null || tags.size() > 0) {
				link.setTags(tags);
			}
			
			if (comments != null || comments.size() > 0) {
				link.setComments(getComments(link));
			}
			l.add(link);
		}
		return l;
	}

}
